using System;
using Oracle.ManagedDataAccess.Client;
using OracleInternal.Common;
using OracleInternal.Network;

namespace OracleInternal.TTC
{
	internal class TTCNotification : TTCFunction
	{
		internal const int REGISTER_KPNDEF = 1;

		internal const int UNREGISTER_KPNDEF = 2;

		internal const int POST_KPNDEF = 3;

		internal const int EXISTINGCLIENT_KPNDEF = 0;

		internal const int NEWCLIENT_KPNDEF = 1;

		internal const int USECLIENTADDR_KPNDEF = 2;

		internal const int CLIENTCON_KPNDEF = 4;

		internal const int KPD_NTFN_CONNID_LEN = 29;

		internal const int KPUN_PRS_RAW = 1;

		internal const int KPUN_VER_10200 = 2;

		internal const int OCI_SUBSCR_NAMESPACE_ANONYMOUS = 0;

		internal const int OCI_SUBSCR_NAMESPACE_AQ = 1;

		internal const int OCI_SUBSCR_NAMESPACE_DBCHANGE = 2;

		internal const int OCI_SUBSCR_NAMESPACE_MAX = 3;

		internal const int KPD_CHNF_OPFILTER = 1;

		internal const int KPD_CHNF_INSERT = 2;

		internal const int KPD_CHNF_UPDATE = 4;

		internal const int KPD_CHNF_DELETE = 8;

		internal const int KPD_CHNF_ROWID = 16;

		internal const int KPD_CQ_QUERYNF = 32;

		internal const int KPD_CQ_BEST_EFFORT = 64;

		internal const int KPD_CQ_CLQRYCACHE = 128;

		internal const int KPD_CHNF_INVALID_REGID = 0;

		internal const int SUBSCR_QOS_RELIABLE = 1;

		internal const int SUBSCR_QOS_PAYLOAD = 2;

		internal const int SUBSCR_QOS_REPLICATE = 4;

		internal const int SUBSCR_QOS_SECURE = 8;

		internal const int SUBSCR_QOS_PURGE_ON_NTFN = 16;

		internal const int SUBSCR_QOS_MULTICBK = 32;

		internal const int OCI_SUBSCR_QOS_HAREG = 128;

		internal const int SUBSCR_QOS_NONDURABLE = 256;

		internal const int SUBSCR_QOS_ASYNC_DEQ = 512;

		internal int m_registrationId;

		internal string m_clientId;

		internal string m_listenerAddress;

		internal TTCNotification(MarshallingEngine mEngine)
			: base(mEngine, 125, 0)
		{
		}

		internal void WriteOKPNMessage(int opcode, int mode, string userName, string location, int numRegistrationInfo, int[] nameSpace, string[] registeredAgentName, byte[][] kpdnrcx, int[] payloadType, int[] qosFlags, int[] timeout, int[] dbchangeOpFilter, int[] dbchangeTxnLag, int[] dbchangeRegistrationId)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)131328, OracleTraceClassName.TTCNotification, OracleTraceFuncName.WriteOKPNMessage);
			}
			try
			{
				int val = 1;
				int val2 = 2;
				WriteFunctionHeader();
				m_marshallingEngine.MarshalUB1((byte)opcode);
				m_marshallingEngine.MarshalUB4(mode);
				byte[] array = null;
				if (userName != null)
				{
					array = m_marshallingEngine.m_dbCharSetConv.ConvertStringToBytes(userName, 0, userName.Length);
					m_marshallingEngine.MarshalPointer();
					m_marshallingEngine.MarshalUB4(array.Length);
				}
				else
				{
					m_marshallingEngine.MarshalNullPointer();
					m_marshallingEngine.MarshalUB4(0L);
				}
				byte[] array2 = null;
				if (location != null)
				{
					array2 = m_marshallingEngine.m_dbCharSetConv.ConvertStringToBytes(location, 0, location.Length);
					m_marshallingEngine.MarshalPointer();
					m_marshallingEngine.MarshalUB4(array2.Length);
				}
				else
				{
					m_marshallingEngine.MarshalNullPointer();
					m_marshallingEngine.MarshalUB4(0L);
				}
				m_marshallingEngine.MarshalPointer();
				m_marshallingEngine.MarshalUB4(numRegistrationInfo);
				m_marshallingEngine.MarshalUB2(val);
				m_marshallingEngine.MarshalUB2(val2);
				if (m_marshallingEngine.NegotiatedTTCVersion >= 4)
				{
					m_marshallingEngine.MarshalNullPointer();
					m_marshallingEngine.MarshalPointer();
					if (m_marshallingEngine.NegotiatedTTCVersion >= 5)
					{
						m_marshallingEngine.MarshalNullPointer();
						m_marshallingEngine.MarshalPointer();
						if (m_marshallingEngine.NegotiatedTTCVersion >= 7)
						{
							m_marshallingEngine.MarshalPointer();
							m_marshallingEngine.MarshalPointer();
							m_marshallingEngine.MarshalPointer();
							m_marshallingEngine.MarshalPointer();
							m_marshallingEngine.MarshalPointer();
							m_marshallingEngine.MarshalSB4(29);
							m_marshallingEngine.MarshalPointer();
						}
					}
				}
				if (array != null)
				{
					m_marshallingEngine.MarshalCHR(array);
				}
				if (array2 != null)
				{
					m_marshallingEngine.MarshalCHR(array2);
				}
				for (int i = 0; i < numRegistrationInfo; i++)
				{
					m_marshallingEngine.MarshalUB4(nameSpace[i]);
					byte[] array3 = null;
					if (registeredAgentName[i] != null)
					{
						array3 = m_marshallingEngine.m_dbCharSetConv.ConvertStringToBytes(registeredAgentName[i], 0, registeredAgentName[i].Length);
					}
					if (array3 != null && array3.Length != 0)
					{
						m_marshallingEngine.MarshalUB4(array3.Length);
						m_marshallingEngine.MarshalCLR(array3, 0, array3.Length);
					}
					else
					{
						m_marshallingEngine.MarshalUB4(0L);
					}
					if (kpdnrcx[i] != null && kpdnrcx[i].Length != 0)
					{
						m_marshallingEngine.MarshalUB4(kpdnrcx[i].Length);
						m_marshallingEngine.MarshalCLR(kpdnrcx[i], 0, kpdnrcx[i].Length);
					}
					else
					{
						m_marshallingEngine.MarshalUB4(0L);
					}
					m_marshallingEngine.MarshalUB4(payloadType[i]);
					if (m_marshallingEngine.NegotiatedTTCVersion >= 4)
					{
						m_marshallingEngine.MarshalUB4(qosFlags[i]);
						int num = 0;
						m_marshallingEngine.MarshalUB4(num);
						m_marshallingEngine.MarshalUB4(timeout[i]);
						int num2 = 0;
						m_marshallingEngine.MarshalUB4(num2);
						m_marshallingEngine.MarshalUB4(dbchangeOpFilter[i]);
						m_marshallingEngine.MarshalUB4(dbchangeTxnLag[i]);
						m_marshallingEngine.MarshalUB4(dbchangeRegistrationId[i]);
						if (m_marshallingEngine.NegotiatedTTCVersion >= 5)
						{
							m_marshallingEngine.MarshalUB1(0);
							m_marshallingEngine.MarshalUB4(0L);
							m_marshallingEngine.MarshalUB1(0);
							m_marshallingEngine.MarshalDALC(null);
							m_marshallingEngine.MarshalSB4(0);
							m_marshallingEngine.MarshalSB8(dbchangeRegistrationId[i]);
						}
					}
				}
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)268566528, OracleTraceClassName.TTCNotification, OracleTraceFuncName.WriteOKPNMessage, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)131584, OracleTraceClassName.TTCNotification, OracleTraceFuncName.WriteOKPNMessage);
				}
			}
		}

		internal void ReceiveOKPNResponse()
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)131328, OracleTraceClassName.TTCNotification, OracleTraceFuncName.ReceiveOKPNResponse);
			}
			bool flag = false;
			try
			{
				m_marshallingEngine.TTCErrorObject.Initialize();
				while (!flag)
				{
					try
					{
						switch (m_marshallingEngine.UnmarshalSB1())
						{
						case 23:
							ProcessServerSidePiggybackFunction(0);
							break;
						case 9:
							if (m_marshallingEngine.HasEOCSCapability)
							{
								m_marshallingEngine.m_endOfCallStatus = m_marshallingEngine.UnmarshalUB4();
							}
							if (m_marshallingEngine.HasFSAPCapability)
							{
								m_marshallingEngine.m_endToEndECIDSequenceNumber = m_marshallingEngine.UnmarshalUB2();
							}
							flag = true;
							break;
						case 8:
						{
							int num = (int)m_marshallingEngine.UnmarshalUB4();
							for (int i = 0; i < num; i++)
							{
								m_marshallingEngine.UnmarshalUB4();
							}
							for (int j = 0; j < num; j++)
							{
								if (j == 0)
								{
									m_registrationId = (int)m_marshallingEngine.UnmarshalUB4();
								}
								else
								{
									m_marshallingEngine.UnmarshalUB4();
								}
							}
							if (m_marshallingEngine.NegotiatedTTCVersion < 5)
							{
								break;
							}
							int num2 = (int)m_marshallingEngine.UnmarshalUB4();
							long num3 = 0L;
							for (int k = 0; k < num2; k++)
							{
								if (k == 0)
								{
									num3 = m_marshallingEngine.UnmarshalSB8();
								}
								else
								{
									m_marshallingEngine.UnmarshalSB8();
								}
								if (m_marshallingEngine.NegotiatedTTCVersion >= 7)
								{
									int num4 = (int)m_marshallingEngine.UnmarshalUB4();
									if (num4 > 0)
									{
										byte[] byteValue = new byte[num4];
										m_marshallingEngine.UnmarshalBuffer(byteValue, 0, num4);
									}
								}
							}
							m_registrationId = (int)num3;
							if (m_marshallingEngine.NegotiatedTTCVersion < 7)
							{
								break;
							}
							int num5 = (int)m_marshallingEngine.UnmarshalUB4();
							_ = new string[num5];
							for (int l = 0; l < num5; l++)
							{
								int num6 = (int)m_marshallingEngine.UnmarshalUB4();
								if (num6 > 0)
								{
									byte[] bytes = new byte[num6];
									int[] intArray = new int[1];
									m_marshallingEngine.UnmarshalCLR(bytes, 0, intArray, num6);
								}
							}
							int num7 = (int)m_marshallingEngine.UnmarshalUB4();
							for (int m = 0; m < num7; m++)
							{
								int num8 = (int)m_marshallingEngine.UnmarshalUB4();
								if (num8 > 0)
								{
									byte[] array = m_marshallingEngine.UnmarshalCHR(num8);
									if (array != null)
									{
										m_listenerAddress = m_marshallingEngine.m_dbCharSetConv.ConvertBytesToString(array, 0, num8);
									}
								}
							}
							int num9 = m_marshallingEngine.UnmarshalUB2();
							if (num9 > 0)
							{
								byte[] array2 = m_marshallingEngine.UnmarshalCHR(num9);
								if (array2 != null)
								{
									m_clientId = m_marshallingEngine.m_dbCharSetConv.ConvertBytesToString(array2, 0, num9);
								}
							}
							break;
						}
						case 15:
							m_marshallingEngine.TTCErrorObject.ReadWarning();
							break;
						case 4:
							m_marshallingEngine.TTCErrorObject.ReadErrorMessage();
							flag = true;
							break;
						default:
							throw new Exception("TTCNotification:ReceiveOKPNResponse - Unexpected Packet received.");
						}
					}
					catch (NetworkException ex)
					{
						if (ex.ErrorCode != 3111)
						{
							throw;
						}
						m_marshallingEngine.m_oracleCommunication.Reset();
					}
					catch (Exception)
					{
						if (m_marshallingEngine.m_oraBufRdr != null)
						{
							m_marshallingEngine.m_oraBufRdr.ClearState();
						}
						m_marshallingEngine.m_oracleCommunication.Break();
						m_marshallingEngine.m_oracleCommunication.Reset();
					}
				}
			}
			catch (Exception ex3)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)268566528, OracleTraceClassName.TTCNotification, OracleTraceFuncName.ReceiveOKPNResponse, ex3);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)131584, OracleTraceClassName.TTCNotification, OracleTraceFuncName.ReceiveOKPNResponse);
				}
			}
		}
	}
}
